home *** CD-ROM | disk | FTP | other *** search
/ Super PC 34 / Super PC 34 (Shareware).iso / spc / UTIL / DJGPP2 / V2 / DJLSR200.ZIP / src / stub / stubedit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-11  |  6.1 KB  |  289 lines

  1. /* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <io.h>
  6. #include <fcntl.h>
  7.  
  8. #include "../../include/stubinfo.h"
  9.  
  10. unsigned long size_of_stubinfo = 0;
  11. char *client_stub_info;
  12.  
  13. void find_info(char *filename)
  14. {  
  15.   FILE *f;
  16.   unsigned char header[4];
  17.   unsigned char test_magic[16];
  18.  
  19.   f = fopen(filename, "rb");
  20.   if (f == 0)
  21.   {
  22.     char buf[100];
  23.     sprintf(buf, "Fatal error in stubedit reading %s", filename);
  24.     perror(buf);
  25.     exit(1);
  26.   }
  27.  
  28.   fseek(f, 512L, 0);
  29.   fread(test_magic, 16, 1, f);
  30.   if (memcmp(test_magic, "go32stub", 8) != 0)
  31.   {
  32.     printf("Error: %s is not a go32 v2.0 or higher stub\n");
  33.     exit(1);
  34.   }
  35.  
  36.   fread(header, 4, 1, f);
  37.   size_of_stubinfo = (header[0]) | (header[1]<<8)
  38.                    | (header[2])<<16 | (header[3]<<24);
  39.  
  40.   fseek(f, 512L, 0);
  41.   client_stub_info = (char *)malloc(size_of_stubinfo);
  42.   fread(client_stub_info, size_of_stubinfo, 1, f);
  43.  
  44.   fclose(f);
  45.   return;
  46. }
  47.  
  48. void store_info(char *filename)
  49. {
  50.   FILE *f;
  51.   f = fopen(filename, "r+b");
  52.   if (f == 0)
  53.   {
  54.     char buf[100];
  55.     sprintf(buf, "Fatal error in stubedit writing %s", filename);
  56.     perror(buf);
  57.     exit(1);
  58.   }
  59.   fseek(f, 512L, 0);
  60.   fwrite(client_stub_info, 1, size_of_stubinfo, f);
  61.   fclose(f);
  62. }
  63.  
  64. char *pose_question(char *question, char *default_answer)
  65. {
  66.   static char response[200];
  67.   printf("%s ? [%s] ", question, default_answer);
  68.   fflush(stdout);
  69.   gets(response);
  70.   if (response[0] == '\0')
  71.     return 0;
  72.   return response;
  73. }
  74.  
  75. typedef void (*PerFunc)(void *address_of_field, char *buffer);
  76.  
  77. void str_v2s(void *addr, char *buf, int len)
  78. {
  79.   if (*(char *)addr == 0)
  80.     strcpy(buf, "\"\"");
  81.   else
  82.   {
  83.     buf[len] = 0;
  84.     strncpy(buf, (char *)addr, len);
  85.   }
  86. }
  87.  
  88. void str_s2v(void *addr, char *buf, int len)
  89. {
  90.   if (strcmp(buf, "\"\"") == 0)
  91.     *(char *)addr = 0;
  92.   else
  93.   {
  94.     ((char *)addr)[len-1] = 0;
  95.     strncpy((char *)addr, buf, len);
  96.   }
  97. }
  98.  
  99. void str_v2s8(void *addr, char *buf)
  100. {
  101.   str_v2s(addr, buf, 8);
  102. }
  103.  
  104. void str_s2v8(void *addr, char *buf)
  105. {
  106.   str_s2v(addr, buf, 8);
  107. }
  108.  
  109. void str_v2s16(void *addr, char *buf)
  110. {
  111.   str_v2s(addr, buf, 16);
  112. }
  113.  
  114. void str_s2v16(void *addr, char *buf)
  115. {
  116.   str_s2v(addr, buf, 16);
  117. }
  118.  
  119. void num_v2s(void *addr, char *buf)
  120. {
  121.   unsigned long v = *(unsigned long *)addr;
  122.   sprintf(buf, "%#lx (%dk)", v, v / 1024L);
  123. }
  124.  
  125. void num_s2v(void *addr, char *buf)
  126. {
  127.   unsigned long r = 0;
  128.   char s = 0;
  129.   sscanf(buf, "%i%c", &r, &s);
  130.   switch (s)
  131.   {
  132.     case 'k':
  133.     case 'K':
  134.       r *= 1024L;
  135.       break;
  136.     case 'm':
  137.     case 'M':
  138.       r *= 1048576L;
  139.       break;
  140.   }
  141.   *(unsigned long *)addr = r;
  142. }
  143.  
  144. struct {
  145.   char *short_name;
  146.   char *long_name;
  147.   int offset_of_field;
  148.   PerFunc val2string;
  149.   PerFunc string2val;
  150. } per_field[] = {
  151.   {
  152.     "minstack",
  153.     "Minimum amount of stack space (bytes/K/M)",
  154.     STUBINFO_MINSTACK,
  155.     num_v2s, num_s2v
  156.   },
  157.   {
  158.     "bufsize",
  159.     "Size of real-memory transfer buffer (bytes/K/M)",
  160.     STUBINFO_MINKEEP,
  161.     num_v2s, num_s2v
  162.   },
  163.   {
  164.     "runfile",
  165.     "Base name of file to actually run (max 8 chars, \"\"=self)",
  166.     STUBINFO_BASENAME,
  167.     str_v2s8, str_s2v8
  168.   },
  169.   {
  170.     "argv0",
  171.     "Value to pass as file component of argv[0] (max 16 chars, \"\"=default)",
  172.     STUBINFO_ARGV0,
  173.     str_v2s16, str_s2v16
  174.   },
  175.   {
  176.     "dpmi",
  177.     "Program to load to provide DPMI services (if needed)",
  178.     STUBINFO_DPMI_SERVER,
  179.     str_v2s16, str_s2v16
  180.   }
  181. };
  182.  
  183. #define NUM_FIELDS (sizeof(per_field) / sizeof(per_field[0]))
  184.  
  185. #define HFORMAT "%-16s %s\n"
  186.  
  187. void give_help(void)
  188. {
  189.   int i;
  190.   fprintf(stderr, "Usage: stubedit [-v] [-h] filename.exe [field=value . . . ]\n");
  191.   fprintf(stderr, "-h = give help   -v = view info  field=value means set w/o prompt\n");
  192.   fprintf(stderr, HFORMAT, "-field-", "-description-");
  193.  
  194.   for (i=0; i < NUM_FIELDS; i++)
  195.     fprintf(stderr, HFORMAT, per_field[i].short_name, per_field[i].long_name);
  196.   exit(1);
  197. }
  198.  
  199. main(int argc, char **argv)
  200. {
  201.   int view_only = 0;
  202.   int i;
  203.   int need_to_save;
  204.  
  205.   if (argc > 1 && strcmp(argv[1], "-h") == 0)
  206.     give_help();
  207.  
  208.   if (argc > 1 && strcmp(argv[1], "-v") == 0)
  209.   {
  210.     view_only = 1;
  211.     argc--;
  212.     argv++;
  213.   }
  214.  
  215.   if (argc < 2)
  216.     give_help();
  217.  
  218.   find_info(argv[1]);
  219.  
  220.   if (view_only)
  221.   {
  222.     char buf[100];
  223.     fprintf(stderr, HFORMAT, "-value-", "-field description-");
  224.     for (i=0; i<NUM_FIELDS; i++)
  225.     {
  226.       if (per_field[i].offset_of_field < size_of_stubinfo)
  227.       {
  228.         per_field[i].val2string(client_stub_info + per_field[i].offset_of_field, buf);
  229.         fprintf(stderr, HFORMAT, buf, per_field[i].long_name);
  230.       }
  231.     }
  232.     exit(0);
  233.   }
  234.  
  235.   if (argc > 2)
  236.   {
  237.     int f, got, got_any = 0;
  238.     char fname[100], fval[100];
  239.     for (i=2; i < argc; i++)
  240.     {
  241.       fname[0] = 0;
  242.       fval[0] = 0;
  243.       sscanf(argv[i], "%[^=]=%s", fname, fval);
  244.       got = 0;
  245.       for (f=0; f<NUM_FIELDS; f++)
  246.       {
  247.         if (strcmp(per_field[f].short_name, fname) == 0)
  248.         {
  249.           got = 1;
  250.           got_any = 1;
  251.           if (per_field[i].offset_of_field < size_of_stubinfo)
  252.           {
  253.             per_field[f].string2val(client_stub_info + per_field[f].offset_of_field, fval);
  254.           }
  255.           else
  256.             fprintf(stderr, "Warning: This stub does not support field %s\n", fname);
  257.         }
  258.       }
  259.       if (!got)
  260.       {
  261.         fprintf(stderr, "Error: %s is not a valid field name.\n", fname);
  262.         give_help();
  263.       }
  264.     }
  265.     if (got_any)
  266.       store_info(argv[1]);
  267.     return 0;
  268.   }
  269.  
  270.   need_to_save = 0;
  271.   for (i=0; i<NUM_FIELDS; i++)
  272.   {
  273.     char buf[100], *resp;
  274.     if (per_field[i].offset_of_field < size_of_stubinfo)
  275.     {
  276.       per_field[i].val2string(client_stub_info + per_field[i].offset_of_field, buf);
  277.       if ((resp = pose_question(per_field[i].long_name, buf)) != 0)
  278.       {
  279.         per_field[i].string2val(client_stub_info + per_field[i].offset_of_field, resp);
  280.         need_to_save = 1;
  281.       }
  282.     }
  283.   }
  284.   if (need_to_save)
  285.     store_info(argv[1]);
  286.  
  287.   return 0;
  288. }
  289.